<?php
namespace App\Modules\Mq\Controllers;

use App\Http\Model\MqExceptionRecord;
use App\Modules\Mq\Services\ProcessService;
use Illuminate\Http\Request;
use App\Lib\Response;
use App\Http\Model\Hint;
use Illuminate\Support\Facades\Redis;

class MqController extends BaseController {

    public function __construct() {
    }

    public function testPush(){
        /*PushService::push(['task' => 'delayed','data' => '15000',], 'delayed', '15000');
        PushService::push(['task' => 'delayed','data' => '10000',], 'delayed', '10000');
        PushService::push(['task' => 'delayed','data' => '5000',], 'delayed', '5000');
        PushService::push(['task' => 'common','data' => 'common',], 'common', '5000');*/
        return Response::json(Hint::SUCCESS);
    }

    /**
     * 处理数据库中的异常数据
     * mq服务请求api服务失败后会重试2次，如果都失败则会写入数据库、发送飞书报警，提醒开发者手动处理
     * 开发者手动触发该接口，会自动处理异常数据。
     */
    public function processDb(Request $request){

        $num = $request->get('num'); //操作的数量
        $num = empty($num) ? 20 : intval($num); //默认每次处理20条，防止处理超时

        $model = new MqExceptionRecord();
        $volist = $model->getDataList($num);

        if(empty($volist)){
            die(Response::json(Hint::SUCCESS,[],'No Exception Data'));
        }

        $lockKey = "MQ_EXCEPTION_DB";
        $lock = redis_lock($lockKey);
        if($lock == false){
            die(Response::json(Hint::SUCCESS,[],'Data Processing, Please Wait'));
        }

        $resp = [];
        foreach ($volist as $key => $vo){
            $data = json_decode($vo['data'],1);

            $resp[$key] = ['id' => $vo['id'], 'request' => $data];

            $processTask = ProcessService::Instance($data['task']);
            if($processTask != null){
                //处理业务
                $result = $processTask->process($vo['data']);
                $resp[$key]['result'] = $result;
                $resp[$key]['desc'] = "Process Finished";
            }else{
                $resp[$key]['result'] = false;
                $resp[$key]['desc'] = "Service Not Found";
            }

            //更新数据库
            $model->updateStatusById($vo['id'],$result);
        }

        redis_unlock($lockKey);

        return Response::json(Hint::SUCCESS,$resp);
    }

    // 分发消息队列的消息给处理类
    public function process (Request $request) {

        $messageId = $request->get('messageId');

        //如果消息id不为空，则验证消息id，防止重复请求
        if (!empty($messageId)) {
            $redisKey = "RABBITMQ:MESSAGE_ID:%s";
            $redisKey = sprintf($redisKey,$messageId);
            $msg = Redis::get($redisKey);
            if (!empty($msg)) {
                return Response::json(Hint::SUCCESS);
            }
            Redis::setex($redisKey,1800,1);
        }
        $body = $request->getContent();

        $bodyArr = json_decode($body, true);

        $processTask = ProcessService::Instance($bodyArr['task']);

        //没找到相应的handler
        if ($processTask == null) {
            return Response::json(Hint::ERROR);
        }
        //处理失败
        $ok =  $processTask->process($bodyArr['data']);
        if (!$ok){
            return Response::json(Hint::ERROR);
        }
        //处理成功
        return Response::json(Hint::SUCCESS);
    }
}